/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { ts, ArkFile, AstTreeUtils } from 'arkanalyzer/lib';
import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger';
import { BaseChecker, BaseMetaData } from '../BaseChecker';
import { Defects, IssueReport } from '../../model/Defects';
import { FileMatcher, MatcherCallback, MatcherTypes } from '../../matcher/Matchers';
import { Rule } from '../../model/Rule';
import { RuleListUtil } from '../../utils/common/DefectsList';

const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'NoMisusedPromisesCheck');
const gMetaData: BaseMetaData = {
    severity: 2,
    ruleDocPath: 'docs/no-misused-promises-check.md',
    description: 'Disallow Promises in places not designed to handle them',
    messages: {
        conditional: 'Expected non-Promise value in a boolean conditional.',
        spread: 'Expected a non-Promise value to be spreaded in an object.',
        voidReturnArgument:
            'Promise returned in function argument where a void return was expected.',
        voidReturnAttribute:
            'Promise-returning function provided to attribute where a void return was expected.',
        voidReturnProperty:
            'Promise-returning function provided to property where a void return was expected.',
        voidReturnReturnValue:
            'Promise-returning function provided to return value where a void return was expected.',
        voidReturnVariable:
            'Promise-returning function provided to variable where a void return was expected.',
    },
    defaultOptions: { checksConditionals: true, checksSpreads: true, checksVoidReturn: true }
};

type Options =
    {
        checksConditionals?: boolean;
        checksSpreads?: boolean;
        checksVoidReturn?:
        | boolean
        | ChecksVoidReturnOptions;
    };

interface ChecksVoidReturnOptions {
    arguments?: boolean;
    attributes?: boolean;
    properties?: boolean;
    returns?: boolean;
    variables?: boolean;
}

function parseCheckVoidReturn(checksVoidReturn: boolean | ChecksVoidReturnOptions | undefined): ChecksVoidReturnOptions | false {
    switch (checksVoidReturn) {
        case false:
            return false;
        case true:
        case undefined:
            return {
                arguments: true,
                attributes: true,
                properties: true,
                returns: true,
                variables: true,
            };

        default:
            return {
                arguments: checksVoidReturn.arguments ?? true,
                attributes: checksVoidReturn.attributes ?? true,
                properties: checksVoidReturn.properties ?? true,
                returns: checksVoidReturn.returns ?? true,
                variables: checksVoidReturn.variables ?? true,
            };
    }
}

const LogicalTypes = [ts.SyntaxKind.AmpersandAmpersandToken, ts.SyntaxKind.BarBarToken];
const CALLBACK_METHODS = ['forEach', 'map', 'filter', 'find', 'every', 'some'];
const PROMISE_METHODS = ['resolve', 'reject', 'all', 'race', 'any', 'allSettled'];
const EVENT_METHODS = ['on', 'once', 'addListener', 'addEventListener', 'onEvent'];

export class NoMisusedPromisesCheck implements BaseChecker {
    readonly metaData: BaseMetaData = gMetaData;
    public rule: Rule;
    public defects: Defects[] = [];
    public issues: IssueReport[] = [];
    private fileMatcher: FileMatcher = {
        matcherType: MatcherTypes.FILE,
    };

    // 以下变量将从局部变量变为类成员变量
    private errorPositions: { line: number, colum: number, message: string, sourceCode: string, generic?: string }[] = [];
    private checksConditionals: boolean = false;
    private checksSpreads: boolean = false;
    private checksVoidReturn: ChecksVoidReturnOptions | false = false;
    private checkedNodes = new Set<ts.Node>();

    public registerMatchers(): MatcherCallback[] {
        const matchFileCb: MatcherCallback = {
            matcher: this.fileMatcher,
            callback: this.check
        };
        return [matchFileCb];
    }

    checkNoMisusedPromises(astTree: ts.SourceFile, option: Options): { line: number, colum: number, message: string, sourceCode: string, generic?: string }[] {
        this.errorPositions = [];
        this.checksConditionals = !!option.checksConditionals;
        this.checksSpreads = !!option.checksSpreads;
        this.checksVoidReturn = parseCheckVoidReturn(option.checksVoidReturn);
        this.checkedNodes.clear();
        this.checkNode(astTree);
        return this.errorPositions;
    }

    // 以下是提取出来的主要检查函数
    private checkNode(node: ts.Node): void {
        this.conditionalChecks(node);
        this.voidReturnChecks(node);
        this.spreadChecks(node);

        // 特别检查new Promise表达式
        this.checkNewPromiseExpression(node);
        node.forEachChild(n => this.checkNode(n));
    }

    private conditionalChecks(node: ts.Node, parameters?: ts.NodeArray<ts.ParameterDeclaration>): void {
        if (!this.checksConditionals) {
            return;
        }

        // 条件表达式
        if (ts.isConditionalExpression(node)) {
            this.checkConditional(node.condition, true, parameters);
        }

        // if, while, do-while 语句
        if (ts.isIfStatement(node) || ts.isWhileStatement(node) || ts.isDoStatement(node)) {
            this.checkConditional(node.expression, true, parameters);
        }

        // for 循环条件
        if (ts.isForStatement(node) && node.condition) {
            this.checkConditional(node.condition, true, parameters);
        }

        // 逻辑运算符
        if (ts.isBinaryExpression(node) && LogicalTypes.includes(node.operatorToken.kind)) {
            if (this.isTestExprForBinaryExpression(node)) {
                // 当整个二元表达式用于条件判断时，两侧都视为测试表达式
                this.checkConditional(node.left, true, parameters);
                this.checkConditional(node.right, true, parameters);
            } else {
                // 否则只检查两侧是否含有Promise
                this.checkConditional(node.left, false, parameters);
                this.checkConditional(node.right, false, parameters);
            }
        }

        // 非操作符
        if (ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.ExclamationToken) {
            this.checkConditional(node.operand, true, parameters);
        }

        // 函数体内部检查
        if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node) || ts.isArrowFunction(node)) {
            if (node.body && ts.isBlock(node.body)) {
                for (const statement of node.body.statements) {
                    this.conditionalChecks(statement, node.parameters);
                }
            }
        }
    }

    // 检查二元表达式是否用于条件判断
    private isTestExprForBinaryExpression(node: ts.BinaryExpression): boolean {
        if (!node.parent) {
            return false;
        }

        return ts.isIfStatement(node.parent) ||
            ts.isWhileStatement(node.parent) ||
            ts.isDoStatement(node.parent) ||
            (ts.isConditionalExpression(node.parent) && node.parent.condition === node);
    }

    private checkConditional(node: ts.Expression, isTestExpr = false, parameters?: ts.NodeArray<ts.ParameterDeclaration>): void {
        // 防止重复检查
        if (this.checkedNodes.has(node)) {
            return;
        }
        this.checkedNodes.add(node);

        // 允许 await 表达式 - 这是正确的用法
        if (ts.isAwaitExpression(node)) {
            // await Promise 是有效的条件表达式
            return;
        }

        // 处理括号表达式
        if (ts.isParenthesizedExpression(node)) {
            this.checkConditional(node.expression, isTestExpr, parameters);
            return;
        }

        // 检查条件上下文中的Promise使用
        const isPromise = this.checkNodeIsPromise(node, parameters);
        if (isPromise && isTestExpr) {
            this.report('conditional', node);
            return;
        }

        // 检查二元表达式
        if (ts.isBinaryExpression(node) && LogicalTypes.includes(node.operatorToken.kind)) {
            // 对于逻辑操作符 && 和 ||，左右两侧都需要检查
            this.checkConditional(node.left, isTestExpr, parameters);
            this.checkConditional(node.right, isTestExpr, parameters);
            return;
        }

        // 空值合并运算符 (??) 需要特殊处理
        if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
            // 当在测试表达式上下文时，才检查右侧
            if (isTestExpr) {
                this.checkConditional(node.right, isTestExpr, parameters);
            }
            return;
        }
    }

    // 处理void相关检查函数
    private voidReturnChecks(node: ts.Node): void {
        if (!this.checksVoidReturn) {
            return;
        }

        // 检查函数参数
        if (this.checksVoidReturn.arguments && ts.isCallExpression(node)) {
            this.checkCallExpressionArgs(node);
        }

        // 检查对象属性
        if (this.checksVoidReturn.properties &&
            (ts.isPropertyAssignment(node) || ts.isShorthandPropertyAssignment(node) || ts.isMethodDeclaration(node))) {
            this.checkProperty(node);
        }

        // 检查变量声明
        if (this.checksVoidReturn.variables && ts.isVariableDeclaration(node)) {
            this.checkVariableDeclaration(node);
        }

        // 检查返回语句
        if (this.checksVoidReturn.returns && ts.isReturnStatement(node)) {
            this.checkReturnStatement(node as ts.ReturnStatement);
        }
    }

    // 检查回调函数
    private checkCallExpressionArgs(node: ts.CallExpression): void {
        // 检查数组方法回调
        this.checkArrayCallbackMethods(node);

        // 检查事件监听方法
        this.checkEventListenerMethods(node);
    }

    // 检查数组方法的回调参数
    private checkArrayCallbackMethods(node: ts.CallExpression): void {
        if (!ts.isPropertyAccessExpression(node.expression)) {
            return;
        }

        const propAccess = node.expression;
        if (!ts.isIdentifier(propAccess.name)) {
            return;
        }

        // 检查是否是数组回调方法或事件方法
        const isCallbackMethod = CALLBACK_METHODS.includes(propAccess.name.text);
        const isEventMethod = EVENT_METHODS.includes(propAccess.name.text);

        if (!(isCallbackMethod || isEventMethod) || node.arguments.length === 0) {
            return;
        }

        // 事件方法通常第二个参数是回调，而数组方法通常第一个参数是回调
        const callbackIndex = isEventMethod ? 1 : 0;
        if (callbackIndex >= node.arguments.length) {
            return;
        }

        const callback = node.arguments[callbackIndex];
        if (this.isAsyncFunction(callback)) {
            this.report('voidReturnArgument', callback);
        }
    }

    // 检查事件监听相关方法
    private checkEventListenerMethods(node: ts.CallExpression): void {
        if (!ts.isPropertyAccessExpression(node.expression) ||
            !ts.isIdentifier(node.expression.name) ||
            node.arguments.length === 0) {
            return;
        }

        const methodName = node.expression.name.text;
        const isEventListener = methodName.includes('on') ||
            methodName.includes('listen') ||
            methodName.includes('subscribe');

        if (!isEventListener) {
            return;
        }

        // 通常最后一个参数是回调
        const callback = node.arguments[node.arguments.length - 1];
        if (this.isAsyncFunction(callback)) {
            this.report('voidReturnArgument', callback);
        }
    }

    // 以下是工具函数
    private report(message: string, reportnode: ts.Node): void {
        const { line, character } = reportnode.getSourceFile().getLineAndCharacterOfPosition(reportnode.getStart());
        this.errorPositions.push({
            line: line + 1,
            colum: character + 1,
            message: message,
            sourceCode: reportnode.getText()
        });
    }

    // 以下是 Promise 检查相关函数
    private checkNodeIsPromise(node: ts.Node, parameters?: ts.NodeArray<ts.ParameterDeclaration>): boolean {
        // 检查直接的Promise标识符
        if (ts.isIdentifier(node) && node.text === 'Promise') {
            return true;
        }

        // 检查Promise参数引用
        if (this.isPromiseParameter(node, parameters)) {
            return true;
        }

        // 检查Promise静态方法调用
        if (ts.isCallExpression(node) && this.isPromiseStaticCall(node)) {
            return true;
        }

        // 检查Promise属性访问
        if (this.isPromisePropertyAccess(node)) {
            return true;
        }

        // 检查async函数
        if (this.isAsyncFunctionNode(node)) {
            return true;
        }

        // 检查变量名是否包含Promise关键字
        if (this.isPromiseRelatedIdentifier(node)) {
            return true;
        }

        // 检查await表达式
        if (ts.isAwaitExpression(node)) {
            return true;
        }

        // 检查括号表达式
        if (ts.isParenthesizedExpression(node)) {
            return this.checkNodeIsPromise(node.expression, parameters);
        }

        // 检查二元表达式中的条件判断
        if (this.isPromiseBinaryExpression(node, parameters)) {
            return true;
        }

        // 检查调用表达式，可能返回Promise
        if (this.isPromiseCallExpression(node)) {
            return true;
        }

        return false;
    }

    private isPromiseRelatedIdentifier(node: ts.Node): boolean {
        return ts.isIdentifier(node) &&
            (node.text.toLowerCase().includes('promise') ||
                node.text.includes('getData') ||
                node.text.includes('async'));
    }

    private isPromiseParameter(node: ts.Node, parameters?: ts.NodeArray<ts.ParameterDeclaration>): boolean {
        if (!ts.isIdentifier(node) || !parameters) {
            return false;
        }

        for (const param of parameters) {
            if (!ts.isIdentifier(param.name)) {
                continue;
            }

            if (param.name.text === node.text && param.type &&
                ts.isTypeReferenceNode(param.type) &&
                ts.isIdentifier(param.type.typeName) &&
                param.type.typeName.text === 'Promise') {
                return true;
            }
        }

        return false;
    }

    private isPromisePropertyAccess(node: ts.Node): boolean {
        return ts.isPropertyAccessExpression(node) &&
            ts.isIdentifier(node.expression) &&
            node.expression.text === 'Promise';
    }

    private isPromiseBinaryExpression(node: ts.Node, parameters?: ts.NodeArray<ts.ParameterDeclaration>): boolean {
        if (!ts.isBinaryExpression(node)) {
            return false;
        }

        if (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||
            node.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
            return this.checkNodeIsPromise(node.left, parameters) ||
                this.checkNodeIsPromise(node.right, parameters);
        }

        return false;
    }

    private isAsyncFunctionNode(node: ts.Node): boolean {
        return (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) &&
            !!node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword);
    }

    private isPromiseCallExpression(node: ts.Node): boolean {
        if (!ts.isCallExpression(node)) {
            return false;
        }

        // 如果函数名包含异步相关词汇
        if (ts.isIdentifier(node.expression) &&
            (node.expression.text.includes('async') ||
                node.expression.text.includes('fetch') ||
                node.expression.text.includes('get') ||
                node.expression.text.includes('load'))) {
            return true;
        }

        // 检查方法调用，例如someObj.getData()
        if (ts.isPropertyAccessExpression(node.expression)) {
            const method = node.expression.name;
            if (ts.isIdentifier(method) &&
                (method.text.includes('async') ||
                    method.text.includes('get') ||
                    method.text.includes('fetch') ||
                    method.text.includes('load'))) {
                return true;
            }
        }

        return false;
    }

    private isPromiseStaticCall(node: ts.CallExpression): boolean {
        if (!ts.isPropertyAccessExpression(node.expression)) {
            return false;
        }

        const expr = node.expression;
        return ts.isIdentifier(expr.expression) &&
            expr.expression.text === 'Promise' &&
            PROMISE_METHODS.includes(expr.name.text);
    }

    // 继续添加其他方法...

    private getOption(): Options {
        let option = this.metaData.defaultOptions;
        if (this.rule && this.rule.option[0]) {
            option = this.rule.option[0] as Options;
        }
        return option;
    }

    public check = (target: ArkFile) => {
        let astTree = AstTreeUtils.getASTNode(
            target.getName(),
            target.getCode()
        );
        let options = this.getOption();
        let errorPositions: { line: number, colum: number, message: string, sourceCode: string, generic?: string }[]
            = this.checkNoMisusedPromises(astTree, options);
        errorPositions.forEach(position => {
            this.addIssueReport(target, position.line, position.colum, position.sourceCode, position.message, position.generic);
        });
    }

    private addIssueReport(arkFile: ArkFile, lineNum: number, startColum: number, code: string, messageId: string, generic: string = '') {
        const severity = this.rule.alert ?? this.metaData.severity;
        let message = this.metaData.messages[messageId];
        let filePath = arkFile.getFilePath();
        let endColum = startColum + code.length - 1;
        let defect = new Defects(lineNum,
            startColum,
            endColum,
            message,
            severity,
            this.rule.ruleId,
            filePath,
            this.metaData.ruleDocPath,
            true,
            false,
            false);
        this.issues.push(new IssueReport(defect, undefined));
        RuleListUtil.push(defect);
    }

    // 新增剩余函数作为类成员
    private spreadChecks(node: ts.Node): void {
        if (!this.checksSpreads) {
            return;
        }

        if (!ts.isSpreadElement(node) && !ts.isSpreadAssignment(node)) {
            return;
        }

        const spreadExpression = ts.isSpreadElement(node) ?
            node.expression : (node as ts.SpreadAssignment).expression;

        // 允许await表达式和括号中的await表达式，这是正确的用法
        if (this.isAwaitExpressionOrParenthesized(spreadExpression)) {
            return;
        }

        // 检查展开对象是否为Promise
        if (this.isPromiseExpression(spreadExpression)) {
            this.report('spread', spreadExpression);
        }
    }

    private isAwaitExpressionOrParenthesized(node: ts.Expression): boolean {
        // 直接await
        if (ts.isAwaitExpression(node)) {
            return true;
        }

        // 括号中的await
        return ts.isParenthesizedExpression(node) &&
            ts.isAwaitExpression(node.expression);
    }

    private isPromiseExpression(node: ts.Expression): boolean {
        // 检查Promise静态方法调用
        if (this.isPromiseStaticMethodCall(node)) {
            return true;
        }

        // 检查Promise属性访问
        if (this.isPromisePropertyReference(node)) {
            return true;
        }

        // 检查Promise标识符
        if (this.isPromiseIdentifier(node)) {
            return true;
        }

        // 检查可能返回Promise的函数调用
        if (ts.isCallExpression(node) && this.isPromiseFunctionCall(node)) {
            return true;
        }

        // 检查变量名是否包含Promise关键字
        if (this.isPromiseRelatedIdentifierExpression(node)) {
            return true;
        }

        // 检查await表达式
        if (ts.isAwaitExpression(node)) {
            return true;
        }

        // 检查括号表达式
        if (ts.isParenthesizedExpression(node)) {
            return this.isPromiseExpression(node.expression);
        }

        // 检查二元表达式中的Promise
        if (this.isPromiseBinaryExpressionForPromiseExpression(node)) {
            return true;
        }

        // 检查函数是否为async
        if (this.isAsyncFunctionNode(node)) {
            return true;
        }

        return false;
    }

    private isPromiseStaticMethodCall(node: ts.Expression): boolean {
        return ts.isCallExpression(node) && this.isPromiseStaticCall(node);
    }

    private isPromisePropertyReference(node: ts.Expression): boolean {
        return ts.isPropertyAccessExpression(node) &&
            ts.isIdentifier(node.expression) &&
            node.expression.text === 'Promise';
    }

    private isPromiseIdentifier(node: ts.Expression): boolean {
        return ts.isIdentifier(node) && node.text === 'Promise';
    }

    private isPromiseFunctionCall(node: ts.CallExpression): boolean {
        return this.isPromiseReturnFunctionWithIdentifier(node) ||
            this.isPromiseReturnFunctionWithPropertyAccess(node);
    }

    private isPromiseRelatedIdentifierExpression(node: ts.Expression): boolean {
        return ts.isIdentifier(node) &&
            (node.text.toLowerCase().includes('promise') ||
                node.text.includes('getData') ||
                node.text.includes('async'));
    }

    private isPromiseBinaryExpressionForPromiseExpression(node: ts.Expression): boolean {
        if (!ts.isBinaryExpression(node)) {
            return false;
        }

        if (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||
            node.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
            return this.isPromiseExpression(node.left) || this.isPromiseExpression(node.right);
        }

        return false;
    }

    private isPromiseReturningFunctionCall(node: ts.Expression): boolean {
        if (!ts.isCallExpression(node)) {
            return false;
        }

        return this.isPromiseReturnFunctionWithIdentifier(node) ||
            this.isPromiseReturnFunctionWithPropertyAccess(node);
    }

    private isPromiseReturnFunctionWithIdentifier(node: ts.CallExpression): boolean {
        if (!ts.isIdentifier(node.expression)) {
            return false;
        }

        const fnName = node.expression.text;
        return fnName.includes('Promise') ||
            fnName.includes('getData') ||
            fnName.includes('async') ||
            fnName.includes('fetch') ||
            fnName.includes('load');
    }

    private isPromiseReturnFunctionWithPropertyAccess(node: ts.CallExpression): boolean {
        if (!ts.isPropertyAccessExpression(node.expression)) {
            return false;
        }

        const propAccess = node.expression;
        return ts.isIdentifier(propAccess.name) &&
            (propAccess.name.text.includes('get') ||
                propAccess.name.text.includes('fetch') ||
                propAccess.name.text.includes('load') ||
                propAccess.name.text.includes('async'));
    }

    private checkNewPromiseExpression(node: ts.Node): void {
        if (!this.isNewPromiseExpression(node)) {
            return;
        }

        const newExpr = node as ts.NewExpression;
        if (!newExpr.arguments || newExpr.arguments.length === 0) {
            return;
        }

        const callback = newExpr.arguments[0];

        // 检查是否为直接的async函数（这是错误用法）
        if (this.isAsyncFunctionNode(callback)) {
            this.report('voidReturnArgument', callback);
            return;
        }

        // 检查函数体中是否有await但没有使用void异步IIFE
        if (this.checkPromiseCallback(callback)) {
            this.report('voidReturnArgument', callback);
        }
    }

    private isNewPromiseExpression(node: ts.Node): boolean {
        if (!ts.isNewExpression(node)) {
            return false;
        }

        return ts.isIdentifier(node.expression) &&
            node.expression.text === 'Promise' &&
            !!node.arguments &&
            node.arguments.length > 0;
    }

    private checkPromiseCallback(callback: ts.Node): boolean {
        if (!((ts.isArrowFunction(callback) || ts.isFunctionExpression(callback)) && callback.body)) {
            return false;
        }

        // 首先检查是否有void异步IIFE模式 - 这是合法用法
        if (this.hasValidVoidAsyncIIFE(callback.body)) {
            return false;
        }

        // 如果不是合法的void异步IIFE模式，检查是否含有await表达式
        return this.hasAwaitExpression(callback.body);
    }

    private hasAwaitExpression(node: ts.Node): boolean {
        if (ts.isAwaitExpression(node)) {
            return true;
        }

        let found = false;
        node.forEachChild(child => {
            if (!found) {
                found = this.hasAwaitExpression(child);
            }
        });

        return found;
    }

    private hasValidVoidAsyncIIFE(node: ts.Node): boolean {
        // 直接检查是否有void (async () => {...})(); 模式
        if (this.hasVoidAsyncIIFE(node)) {
            return true;
        }

        // 检查是否是特定模式： void + async 立即调用函数
        const text = node.getText();
        return text.includes('void') &&
            text.includes('async') &&
            (text.includes('() =>') || text.includes('function'));
    }

    private hasVoidAsyncIIFE(node: ts.Node): boolean {
        // 检查表达式语句是否包含'void'关键字后接一个async IIFE
        if (this.isVoidAsyncIIFE(node)) {
            return true;
        }

        // 递归检查所有子节点
        let found = false;
        node.forEachChild(child => {
            if (!found) {
                found = this.hasVoidAsyncIIFE(child);
            }
        });

        return found;
    }

    private isVoidAsyncIIFE(node: ts.Node): boolean {
        if (!ts.isPrefixUnaryExpression(node)) {
            return false;
        }

        const firstToken = node.getFirstToken();
        if (!firstToken || firstToken.kind !== ts.SyntaxKind.VoidKeyword) {
            return false;
        }

        if (!ts.isCallExpression(node.operand)) {
            return false;
        }

        const expr = node.operand.expression;
        return (ts.isArrowFunction(expr) || ts.isFunctionExpression(expr)) &&
            !!expr.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword);
    }

    private isAsyncFunction(node: ts.Node): boolean {
        // 检查async箭头函数或函数表达式
        if (this.isAsyncFunctionNode(node)) {
            return true;
        }

        // 检查返回值是否为Promise类型
        if (this.hasPromiseReturnType(node)) {
            return true;
        }

        // 检查函数体内是否包含await
        if (this.hasFunctionBodyWithAwait(node)) {
            return true;
        }

        // 检查Promise静态方法调用
        if (ts.isCallExpression(node) && this.isPromiseStaticCall(node)) {
            return true;
        }

        // 检查返回Promise的函数
        if (this.returnsFunctionWithPromise(node)) {
            return true;
        }

        // 检查函数名是否包含异步相关词汇
        if (this.hasAsyncFunctionName(node)) {
            return true;
        }

        return false;
    }

    private hasPromiseReturnType(node: ts.Node): boolean {
        if (!ts.isArrowFunction(node) && !ts.isFunctionExpression(node)) {
            return false;
        }

        if (!node.type) {
            return false;
        }

        return ts.isTypeReferenceNode(node.type) &&
            ts.isIdentifier(node.type.typeName) &&
            node.type.typeName.text === 'Promise';
    }

    private hasFunctionBodyWithAwait(node: ts.Node): boolean {
        if (!ts.isArrowFunction(node) && !ts.isFunctionExpression(node)) {
            return false;
        }

        if (!node.body) {
            return false;
        }

        if (ts.isBlock(node.body)) {
            let hasAwait = false;
            const visitor = (n: ts.Node): void => {
                if (ts.isAwaitExpression(n)) {
                    hasAwait = true;
                }
                if (!hasAwait) {
                    ts.forEachChild(n, visitor);
                }
            };
            ts.forEachChild(node.body, visitor);
            return hasAwait;
        }

        return ts.isAwaitExpression(node.body);
    }

    private returnsFunctionWithPromise(node: ts.Node): boolean {
        if (!ts.isArrowFunction(node) && !ts.isFunctionExpression(node)) {
            return false;
        }

        if (!node.body) {
            return false;
        }

        // 如果body是一个表达式，检查是否返回Promise
        if (!ts.isBlock(node.body) && this.isPromiseExpression(node.body)) {
            return true;
        }

        // 如果body是代码块，检查是否包含return Promise...
        if (ts.isBlock(node.body) && node.body.statements.length > 0) {
            const lastStatement = node.body.statements[node.body.statements.length - 1];
            return ts.isReturnStatement(lastStatement) &&
                !!lastStatement.expression &&
                this.isPromiseExpression(lastStatement.expression);
        }

        return false;
    }

    private hasAsyncFunctionName(node: ts.Node): boolean {
        return ts.isIdentifier(node) &&
            (node.text.includes('async') ||
                node.text.includes('get') ||
                node.text.includes('fetch'));
    }

    private checkProperty(node: ts.Node): void {
        if (ts.isPropertyAssignment(node)) {
            const propAssign = node as ts.PropertyAssignment;
            // 检查属性值是否为async函数
            if (this.isPropertyExpectingVoidFn(node) && this.isAsyncFunction(propAssign.initializer)) {
                this.report('voidReturnProperty', propAssign.name);
            }
        } else if (ts.isShorthandPropertyAssignment(node)) {
            const shorthand = node as ts.ShorthandPropertyAssignment;
            // 检查简写属性是否为async函数
            if (this.isPropertyExpectingVoidFn(node) &&
                ts.isIdentifier(shorthand.name) &&
                this.isIdentifierRefToAsync(shorthand.name)) {
                this.report('voidReturnProperty', shorthand.name);
            }
        } else if (ts.isMethodDeclaration(node)) {
            if (ts.isComputedPropertyName(node.name)) {
                return;
            }

            // 检查方法是否为async
            if (node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) &&
                this.isMethodExpectingVoidReturn(node)) {
                this.report('voidReturnProperty', node.name);
            }
        }
    }

    private isIdentifierRefToAsync(identifier: ts.Identifier): boolean {
        // 简单检查名称包含async
        return identifier.text.includes('async') ||
            identifier.text.includes('fetch') ||
            identifier.text.includes('get');
    }

    private isPropertyExpectingVoidFn(node: ts.Node): boolean {
        // 检查父对象类型声明
        const parent = node.parent;
        if (parent && ts.isObjectLiteralExpression(parent)) {
            const grandParent = parent.parent;

            if (grandParent && ts.isVariableDeclaration(grandParent) && grandParent.type) {
                // 检查对象字面量的类型声明
                const typeText = grandParent.type.getText();
                if (typeText.includes(': () => void') ||
                    (typeText.includes(': (') && typeText.includes('=> void'))) {
                    return true;
                }
            }

            if (grandParent) {
                const grandParentText = grandParent.getText();
                // 检查是否有声明为返回void的函数属性
                if (grandParentText.includes(': () => void') ||
                    (grandParentText.includes(': (') && grandParentText.includes('=> void'))) {
                    return true;
                }
            }
        }

        return false;
    }

    private isMethodExpectingVoidReturn(node: ts.MethodDeclaration): boolean {
        if (node.type && node.type.kind === ts.SyntaxKind.VoidKeyword) {
            return true;
        }

        // 检查方法是否在包含void返回类型的接口或类中
        const parent = node.parent;
        if (parent &&
            (ts.isClassDeclaration(parent) || ts.isInterfaceDeclaration(parent)) &&
            parent.heritageClauses) {
            return true;
        }

        return false;
    }

    private checkVariableDeclaration(node: ts.VariableDeclaration): void {
        if (!node.initializer) {
            return;
        }

        // 检查类型注解是否表明返回void
        if (node.type && ts.isTypeNode(node.type)) {
            const typeText = node.type.getText();
            if (typeText.includes('() => void') || typeText.includes('=> void')) {
                if (this.isAsyncFunction(node.initializer)) {
                    this.report('voidReturnVariable', node.initializer);
                }
                return;
            }
        }

        // 检查变量声明上下文
        if (node.parent && node.parent.parent) {
            const declarationText = node.parent.parent.getText();
            if ((declarationText.includes(': () => void') ||
                (declarationText.includes(': Function') && declarationText.includes('void'))) &&
                this.isAsyncFunction(node.initializer)) {
                this.report('voidReturnVariable', node.initializer);
            }
        }
    }

    private checkReturnStatement(node: ts.ReturnStatement): void {
        if (!node.expression) {
            return;
        }

        const voidFunctionDeclaration = this.findEnclosingVoidFunction(node);
        if (!voidFunctionDeclaration) {
            return;
        }

        // 在void返回类型的函数内部返回Promise
        if (this.isAsyncFunction(node.expression) || this.isPromiseExpression(node.expression)) {
            this.report('voidReturnReturnValue', node.expression);
        }
    }

    // 查找包含当前节点的返回类型为void的函数
    private findEnclosingVoidFunction(node: ts.Node): ts.Node | null {
        let current: ts.Node = node;

        while (current.parent) {
            current = current.parent;

            if (!this.isFunctionLikeDeclaration(current)) {
                continue;
            }

            // 使用类型断言处理函数节点类型
            const funcNode = current as ts.FunctionDeclaration | ts.MethodDeclaration | ts.ArrowFunction;
            if (funcNode.type && funcNode.type.kind === ts.SyntaxKind.VoidKeyword) {
                return current;
            }
        }

        return null;
    }

    // 检查节点是否为函数声明
    private isFunctionLikeDeclaration(node: ts.Node): boolean {
        return ts.isFunctionDeclaration(node) ||
            ts.isMethodDeclaration(node) ||
            ts.isArrowFunction(node);
    }
}
